package com.fishbone.cloud.auth.security.handler;

import com.fishbone.cloud.auth.security.model.BasicUser;
import com.fishbone.cloud.auth.security.model.FishBoneUser;
import com.fishbone.common.utils.FastJsonUtil;
import com.fishbone.common.utils.Func;
import com.fishbone.core.api.ResponseEntity;
import com.fishbone.jwt.JwtTokenGenerator;
import com.fishbone.jwt.JwtTokenPair;
import com.fishbone.jwt.constants.AuthConstants;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.http.MediaType;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName MyAuthenticationSuccessHandler
 * @Author huyaxi
 * @DATE 2019/8/27 9:45
 */

@Slf4j
@Component
@AllArgsConstructor
public class FishBoneAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    private final JwtTokenGenerator jwtTokenGenerator;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
        FishBoneUser fishBoneUser = (FishBoneUser) authentication.getPrincipal();
        log.info("登录成功,当前登录用户:{}", FastJsonUtil.toJSONString(fishBoneUser));
        SecurityContextHolder.getContext().setAuthentication(authentication);
        Map<String,Object> claims = new HashMap<>(16);
        claims.put(AuthConstants.ACCOUNT,fishBoneUser.getAccount());
        claims.put(AuthConstants.UID,fishBoneUser.getUserId());
        claims.put(AuthConstants.TENANT_ID,fishBoneUser.getTenantId());
        claims.put(AuthConstants.ROLE_IDS, Func.join(fishBoneUser.getRoleIds()));
        String aud = jwtTokenGenerator.generateAud(fishBoneUser.getAccount(), fishBoneUser.getUserId(), fishBoneUser.getTenantId());
        JwtTokenPair jwtTokenPair = jwtTokenGenerator.jwtTokenPair(aud, claims);
        renderToken(httpServletResponse, jwtTokenPair,fishBoneUser);
    }

    /**
     * 渲染返回 token 页面,因为前端页面接收的都是Result对象，故使用application/json返回
     *
     * @param response
     * @throws IOException
     */
    private void renderToken(HttpServletResponse response, JwtTokenPair jwtTokenPair, FishBoneUser fishBoneUser) throws IOException {
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        response.setCharacterEncoding("UTF-8");
        BasicUser currentUser = new BasicUser();
        Map<String,Object> loginSuccessResult = new HashMap<>(16);
        loginSuccessResult.put("token",jwtTokenPair.getAccessToken());
        loginSuccessResult.put("user",currentUser);
        BeanUtils.copyProperties(fishBoneUser,currentUser);
        response.getWriter().write(FastJsonUtil.toJSONString(ResponseEntity.data(loginSuccessResult)));
    }
}
